export class ArrayMap<K, V>{
    public map = new Map<K, V>()
    public array: V[] = []
    public indexMap = new Map<V, number>()
    public get length(): number {
        return this.array.length
    }
    public get(key: K): V {
        return this.map.get(key)
    }
    public set(key: K, value: V) {
        const index = this.indexMap.get(value)

        if (index == undefined) {
            this.array.push(value)
            this.indexMap.set(value, this.array.length - 1)
            this.map.set(key, value)
        }
    }
    has(key: K): boolean {
        return this.map.has(key)
    }
    public delete(key: K) {
        let value = this.map.get(key)
        if (value != null) {
            this.map.delete(key)
            const index = this.indexMap.get(value)
            this.array[index] = this.array[this.array.length - 1]
            this.indexMap.delete(value)
            const switchEcsEntity = this.array[index]
            if (switchEcsEntity !== value) {
                this.indexMap.set(value, index)
            }
            this.array.length -= 1
        }
    }

    public forEach(callbackfn: (value: V, index: number, array: V[]) => void, thisArg?: any) {
        this.array.forEach(callbackfn, thisArg)
    }

    public clear() {
        this.map.clear()
        this.indexMap.clear()
        this.array = []
    }
}

export class Singleton {
    static _instance
    static instance<T extends {}>(this: new () => T): T {
        if (!(<any>this)._instance) {
            (<any>this)._instance = new this();
        }
        const result =(<any>this)._instance
        
        return result;
    }
}

export function fixNumber(num: number, n: number = 10) {
    return Math.round(num * Math.pow(10, n)) / Math.pow(10, n)
}